#include "chatserver.h"

static const QLatin1String serviceUuid("e8e10f95-1a70-4b27-9ccf-02010264e9c8");

chatserver::chatserver(QObject *parent) : QObject(parent),rfcommServer(nullptr)
{

}

chatserver::~chatserver()
{
    this->stopServer();
}

/* 开启服务端，设置服务端使用 rfcomm 协议与 serviceInfo 的一些属性 */
void chatserver::startServer(const QBluetoothAddress& localAdapter)
{
    qDebug()<<"chatserver::startServer" << " localAdapter = "<<localAdapter<<" rfcommServer = "<<rfcommServer;
    if (rfcommServer)
        return;

    rfcommServer = new QBluetoothServer(QBluetoothServiceInfo::RfcommProtocol, this);
    connect(rfcommServer, SIGNAL(newConnection()), this,SLOT(clientConnected()));
    bool result = rfcommServer->listen(localAdapter);
    if (!result) {
        qWarning()<<"[chatserver::startServer]Cannot bind chat serverto"<<localAdapter.toString();
        return;
    }

    // 表示蓝牙串口配置文件
    QBluetoothServiceInfo::Sequence classId;
    classId<<QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::SerialPort));

    // 指定蓝牙服务支持的配置文件
    serviceInfo.setAttribute(QBluetoothServiceInfo::BluetoothProfileDescriptorList,classId);

    classId.prepend(QVariant::fromValue(QBluetoothUuid(serviceUuid)));

    // 服务类别ID列表，用于指定服务支持的类别
    serviceInfo.setAttribute(QBluetoothServiceInfo::ServiceClassIds,classId);

    // 指定该服务支持的蓝牙配置文件
    serviceInfo.setAttribute(QBluetoothServiceInfo::BluetoothProfileDescriptorList,classId);

    // 服务名称，即"Bt Chat Server"
    serviceInfo.setAttribute(QBluetoothServiceInfo::ServiceName,tr("Bt Chat Server"));

    // 服务描述
    serviceInfo.setAttribute(QBluetoothServiceInfo::ServiceDescription,tr("Example bluetooth chat server"));
    // 服务UUID，用于唯一标识该服务
    serviceInfo.setAttribute(QBluetoothServiceInfo::ServiceProvider,tr("qt-project.org"));

    // 将服务的UUID设置为serviceUuid
    serviceInfo.setServiceUuid(QBluetoothUuid(serviceUuid));

    QBluetoothServiceInfo::Sequence publicBrowse;
    publicBrowse<<QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::PublicBrowseGroup));
    serviceInfo.setAttribute(QBluetoothServiceInfo::BrowseGroupList,publicBrowse);

    // 存储协议描述符列表
    QBluetoothServiceInfo::Sequence protocolDescriptorList;
    QBluetoothServiceInfo::Sequence protocol;
    // protocolDescriptorList序列中的第一个元素是L2CAP协议
    protocol<<QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::L2cap));
    protocolDescriptorList.append(QVariant::fromValue(protocol));

    protocol.clear();
    protocol<<QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::Rfcomm))<<QVariant::fromValue(quint8(rfcommServer->serverPort()));
    protocolDescriptorList.append(QVariant::fromValue(protocol));
    serviceInfo.setAttribute(QBluetoothServiceInfo::ProtocolDescriptorList,protocolDescriptorList);
    // 将创建的蓝牙服务注册到本地适配器上
    serviceInfo.registerService(localAdapter);
}


/* 停止服务端 */
void chatserver::stopServer()
{
    // Unregister service
    serviceInfo.unregisterService();

    // Close sockets
    qDeleteAll(clientSockets);

    // Close server
    delete rfcommServer;
    rfcommServer = 0;
}


/* 主动断开连接 */
void chatserver::disconnect()
{
    qDebug()<<"Going to disconnect in server";

    foreach (QBluetoothSocket *socket, clientSockets) {
         qDebug()<<"sending data in server!";
         socket->close();
    }
}

void chatserver::messageReceived(const QString &sender, const QString &message)
{

}

void chatserver::clientConnected(const QString &name)
{

}

void chatserver::clientDisconnected(const QString &name)
{

}

/* 发送消息 */
void chatserver::sendMessage(const QString &message)
{
    qDebug()<<"Going to send message in server: " << message;
    QByteArray text = message.toUtf8() + '\n';
    foreach (QBluetoothSocket *socket, clientSockets) {
        qDebug()<<"sending data in server!";
        socket->write(text);
    }
    qDebug()<<"server sending done!";
}

/* 客户端连接 */
void chatserver::clientConnected()
{
    qDebug()<<"clientConnected";

    QBluetoothSocket *socket = rfcommServer->nextPendingConnection();
    if (!socket)
        return;

    connect(socket, SIGNAL(readyRead()), this, SLOT(readSocket()));
    connect(socket, SIGNAL(disconnected()), this,SLOT(clientDisconnected()));
    clientSockets.append(socket);
    socketsPeername.append(socket->peerName());
    emit sig_clientConnected(socket->peerName());
}

/* 客户端断开连接 */
void chatserver::clientDisconnected()
{
    QBluetoothSocket *socket = qobject_cast<QBluetoothSocket*>(sender());
    if (!socket)
        return;

    if (clientSockets.count() != 0) {
        QString peerName;

        if (socket->peerName().isEmpty())
            peerName = socketsPeername.at(clientSockets.indexOf(socket));
        else
            peerName = socket->peerName();

        emit sig_clientDisconnected(peerName);

        clientSockets.removeOne(socket);
        socketsPeername.removeOne(peerName);
    }

    socket->deleteLater();
}

 /* 从 Socket 里读取数据 */
void chatserver::readSocket()
{
    QBluetoothSocket *socket = qobject_cast<QBluetoothSocket*>(sender());
    if (!socket)
        return;

    while (socket->bytesAvailable()) {
        QByteArray line = socket->readLine().trimmed();
        qDebug()<<QString::fromUtf8(line.constData(),
        line.length())<<endl;
        emit sig_messageReceived(socket->peerName(),
        QString::fromUtf8(line.constData(),line.length()));
        qDebug()<<QString::fromUtf8(line.constData(),
        line.length())<<endl;
    }
}
